import os
import rsa
import pickle
import socket as sk





class Socket:
	def __init__(self,ipversion=4):
		if ipversion==4:
			self.sock = sk.socket(sk.AF_INET,sk.SOCK_STREAM)
		elif ipversion==6:
			self.sock = sk.socket(sk.AF_INET6,sk.SOCK_STREAM)
		self.pubkey,self.privkey = rsa.newkeys(1024)
		self.pubkey_bin = pickle.dumps(self.pubkey)
		self.max_lenth = 1024/8-11

	def bind(self,ip_port):
		self.sock.bind(ip_port)

	def listen(self,max_conn=5):
		self.sock.listen(max_conn)

	def connect(self,ip_port):
		self.sock.connect(ip_port)
		self.opposite_Pubkey = pickle.loads(self.sock.recv(1024))
		self.sock.sendall(self.pubkey_bin)

	def accept(self):
		conn,addr = self.sock.accept()
		conn.sendall(self.pubkey_bin)
		opposite_Pubkey = pickle.loads(conn.recv(1024))
		return warp_connection(conn,self.privkey,opposite_Pubkey),addr

	def sendall(self,Bytes):
		msg = bytes('','utf-8')
		
		with open('cache1.cache','wb') as f:
			f.write(Bytes)
		with open('cache1.cache','rb') as f:
			data = f.read(32)
			while data:
				msg += rsa.encrypt(data,self.opposite_Pubkey)
				data = f.read(32)
		self.sock.sendall(msg+bytes('exit|&|quit','utf-8'))
		os.system('del cache1.cache')

	def recvall(self):
		
		buf = bytes('','utf-8')
		while True:
			data = self.sock.recv(1024)
			buf += data
			if bytes('exit|&|quit','utf-8') in data:
				buf = buf[:-11]
				break
			
		with open('cache2.cache','wb') as f:
			f.write(buf)
		
		msg = bytes('','utf-8')
		with open('cache2.cache','rb') as f:
			data = f.read(128)
			while data:
				msg += rsa.decrypt(data,self.privkey)
				data = f.read(128)
		os.system('del cache2.cache')
		return msg

	def close(self):
		self.sock.close()


class warp_connection:
	def __init__(self,conn,privkey,opposite_Pubkey):
		self.sock = conn
		self.privkey = privkey
		self.opposite_Pubkey = opposite_Pubkey

	def sendall(self,Bytes):
		with open('cache1.cache','wb') as f:
			f.write(Bytes)

		msg = bytes('','utf-8')
		with open('cache1.cache','rb') as f:
			data = f.read(32)
			while data:
				msg += rsa.encrypt(data,self.opposite_Pubkey)
				data = f.read(32)
		self.sock.sendall(msg+bytes('exit|&|quit','utf-8'))
		os.system('del cache1.cache')

	def recvall(self):
	
		buf = bytes('','utf-8')
		while True:
			data = self.sock.recv(1024)
			buf += data
			if bytes('exit|&|quit','utf-8') in data:
				buf = buf[:-11]
				break
			
		with open('cache2.cache','wb') as f:
			f.write(buf)
		
		msg = bytes('','utf-8')
		with open('cache2.cache','rb') as f:
			data = f.read(128)
			while data:
				msg += rsa.decrypt(data,self.privkey)
				data = f.read(128)
		os.system('del cache2.cache')
		return msg

	def close(self):
		self.sock.close()


if __name__ == '__main__':
	pass
	# sock = Socket()
	# with open('xxx.xx','wb') as f:
	# 	f.write(bytes('asdfl;ajsastefijklsejfio4wertueriiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiojjkrhgkdfjiotgstjwioruiowehresfdasfkldsa','utf-8'))

	# with open('xxx.xx','rb') as f:
	# 	line = f.read(50)
	# 	while line:
	# 		print(str(line,'utf-8'))
	# 		line = f.read(50)

	# s = ''
	# li = []
	# for i in range(len(s)//50):
	# 	li.append(s[50*i:50*(i+1)])
	# li.append(s[50*(i+1):])
	# print('\n'.join(li))






































